﻿// Author:  Marco van Wieren <mailto:mvwieren@gmail.com>
// Year:    2012
// License: Microsoft Public License (Ms-PL)

using System;
using System.Text;
using System.Linq;
using System.Collections.Generic;
using Microsoft.SharePoint;
using Microsoft.SharePoint.Taxonomy;

namespace Mvw.SharePoint.Taxonomy.AutoTagging
{
    public class WorkspaceTermInfo
    {
        private string termStoreName = string.Empty;
        public string TermStoreName
        {
            get
            {
                return termStoreName;
            }
            set
            {
                termStoreName = value;
            }
        }

        private string termSetId = string.Empty;
        public string TermSetId
        {
            get
            {
                return termSetId;
            }
            set
            {
                termSetId = value;
            }
        }

        private string taxFieldStaticName = string.Empty;
        public string TaxFieldStaticName
        {
            get
            {
                return taxFieldStaticName;
            }
            set
            {
                taxFieldStaticName = value;
            }
        }

        private List<string> termIds = new List<string>();
        public List<string> TermIds
        {
            get
            {
                return termIds;
            }
            set
            {
                termIds = value;
            }
        }

        private bool allowMultipleValues;
        public bool AllowMultipleValues
        {
            get
            {
                return allowMultipleValues;
            }
            set
            {
                allowMultipleValues = value;
            }
        }

        private bool isValid = false;
        public bool IsValid
        {
            get
            {
                return isValid;
            }
        }

        // Default constructor
        public WorkspaceTermInfo()
        {
        }

        // Constructor from WorkspaceTermInfo.ToString() output
        public WorkspaceTermInfo(string workspaceTermInfo)
        {
            if(workspaceTermInfo == null) 
            {
                return;
            }
            var workspaceTermInfoArr = workspaceTermInfo.Split(';');
            if (workspaceTermInfoArr.Length % 5 != 0 || workspaceTermInfoArr.Length <= 0)
            {
                return;
            }
            termStoreName = workspaceTermInfoArr[0];
            termSetId = workspaceTermInfoArr[1];
            taxFieldStaticName = workspaceTermInfoArr[2];
            termIds = workspaceTermInfoArr[3].Split(',').ToList<string>();
            allowMultipleValues = bool.Parse(workspaceTermInfoArr[4]);

            isValid = validate(); // Tell the outside world we were able to successfully parse the input
        }

        // Constructor from a TaxonomyField
        public WorkspaceTermInfo(TaxonomyField taxonomyField, string strTaxonomyFieldValue, SPSite site)
        {
            var session = new TaxonomySession(site);
            if (session.TermStores.Count <= 0)
            {
                return;
            }

            var termStore = session.TermStores[taxonomyField.SspId];
            if (termStore == null)
            {
                return;
            }

            if (termStore.GetTermSet(taxonomyField.TermSetId) == null)
            {
                return;
            }

            this.termStoreName = termStore.Name;
            this.termSetId = taxonomyField.TermSetId.ToString();
            this.taxFieldStaticName = taxonomyField.StaticName;

            if (taxonomyField.AllowMultipleValues) // Multiple TermGuids will be added 
            {
                foreach (var taxFieldValue in new TaxonomyFieldValueCollection(strTaxonomyFieldValue))
                {
                    this.AddTermId(taxFieldValue.TermGuid.ToString());
                }
            }
            else // Only one TermGuid will be added 
            {
                this.AddTermId(new TaxonomyFieldValue(strTaxonomyFieldValue).TermGuid.ToString());
            }
            this.allowMultipleValues = taxonomyField.AllowMultipleValues;

            isValid = validate();
        }

        public void AddTermId(string termId)
        {
            this.termIds.Add(termId);
        }

        private bool termIdsIsValid() 
        {
            foreach (var termId in termIds)
            {
                try
                {
                    var guid = new Guid(termId);
                }
                catch (Exception e)
                {
                    if (termId.Length == 0)
                    {
                        continue; // An empty value (no value selected) should not invalidate the whole WorkspaceTermInfo
                    }
                    return false;
                }
            }
            return true;
        }

        private bool validate()
        {
            if (termStoreName.Length == 0)
            {
                return false;
            }

            if (termSetId.Length == 0)
            {
                return false;
            }

            if (taxFieldStaticName.Length == 0)
            {
                return false;
            }

            if (!termIdsIsValid())
            {
                return false;
            }
            return true;
        }


        public override string ToString()
        {
            return termStoreName + ";" +
                termSetId + ";" +
                taxFieldStaticName + ";" +
                string.Join(",", termIds.ToArray()) + ";" +
                allowMultipleValues.ToString();
        }
    }
}
